home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 33
/
Amiga Format AFCD33 (Issue 117, Dec 1998).iso
/
-seriously_amiga-
/
archivers
/
unrar
/
src-orig
/
extract.c
< prev
next >
Wrap
Text File
|
1998-09-07
|
9KB
|
342 lines
void ExtrFile(void)
{
struct FileStat FS;
char DestFileName[NM],*ChPtr;
long FileCount=0,TotalFileCount,ErrCount=0;
int SkipSolid,ExtrFile,MDCode,Size,AllArgsUsed;
int UserReject,TmpPassword=0,BrokenFile;
int FirstFile;
GetNextArchive:
if (UnpMemory!=NULL)
{
free(UnpMemory);
UnpMemory=NULL;
}
while (ReadArcName())
{
SkipToFirstVol:
TotalFileCount=ArgUsed=AllArgsUsed=0;
FirstFile=1;
if ((ArcPtr=wopen(ArcName,READBINARY,M_DENYWRITE))==NULL)
continue;
if (TmpPassword!=0)
TmpPassword=Password[0]=0;
if (!IsArchive())
{
mprintf(MNotRAR,ArcName);
tclose(ArcPtr);
continue;
}
if (MainCommand[0]=='T')
mprintf(MExtrTest,ArcName);
else
mprintf(MExtracting,ArcName);
ViewComment();
if ((UnpMemory=malloc(UNP_MEMORY))==NULL)
{
mprintf(MExtrOutMem);
ErrExit(EEMPTY,MEMORY_ERROR);
}
tseek(ArcPtr,NewMhd.HeadSize-MainHeadSize,SEEK_CUR);
UnpVolume=0;
while (1)
{
Size=ReadBlock(FILE_HEAD | READSUBBLOCK);
if (Size<=0 && UnpVolume==0)
break;
if (BlockHead.HeadType==SUB_HEAD)
{
tseek(ArcPtr,NextBlockPos,SEEK_SET);
continue;
}
if (AllArgsUsed)
break;
ConvertPath(ArcFileName,ArcFileName);
ConvertFlags();
if ((NewLhd.Flags & LHD_SPLIT_BEFORE) && SolidType && FirstFile)
{
tclose(ArcPtr);
ChPtr=strrchr(ArcName,'.');
if (ChPtr==NULL || stricomp(ChPtr,".rar")!=0)
{
SetExt(ArcName,"rar");
if (FileExist(ArcName))
goto SkipToFirstVol;
SetExt(ArcName,"exe");
if (FileExist(ArcName))
goto SkipToFirstVol;
}
mprintf(MNeedFirstVol);
if (TotalArcCount>1)
goto GetNextArchive;
else
ErrExit(EEMPTY,FATAL_ERROR);
}
FirstFile=0;
if (UnpVolume && Size==0 && !MergeArchive(0))
{
ErrCount++;
ExitCode=WARNING;
goto GetNextArchive;
}
UnpVolume=(NewLhd.Flags & LHD_SPLIT_AFTER);
tseek(ArcPtr,NextBlockPos-NewLhd.PackSize,SEEK_SET);
TestMode=0;
ExtrFile=0;
SkipSolid=0;
if (IsProcessFile(COMPARE_PATH) && (NewLhd.Flags & LHD_SPLIT_BEFORE)==0
|| (SkipSolid=SolidType)!=0)
{
if (NewLhd.Flags & LHD_PASSWORD)
{
if (*Password==0)
{
if (GetPassword(1)!=1)
ErrExit(EEMPTY,USER_BREAK);
TmpPassword=(SolidType) ? 2 : 1;
}
else
if (TmpPassword==1)
{
mprintf(MUseCurPsw,ArcFileName);
Ask(MYesNoAll);
switch(Choice)
{
case -1:
ErrExit(EEMPTY,USER_BREAK);
case 2:
if (GetPassword(1)!=1)
ErrExit(EEMPTY,USER_BREAK);
break;
case 3:
TmpPassword=2;
break;
}
}
}
strcpy(DestFileName,ExtrPath);
if (MainCommand[0]=='E')
strcat(DestFileName,PointToName(ArcFileName));
else
strcat(DestFileName,ArcFileName);
ExtrFile=!SkipSolid;
if ((Opt.FreshFiles || Opt.UpdateFiles) && (MainCommand[0]=='E' || MainCommand[0]=='X'))
{
if (GetFileStat(DestFileName,&FS))
{
if ( FS.FileTime >= NewLhd.FileTime)
ExtrFile=0;
}
else
if (Opt.FreshFiles)
ExtrFile=0;
}
if (NewLhd.UnpVer<13 || NewLhd.UnpVer>UNP_VER)
{
mprintf(MExtrUnknMeth,ArcFileName);
ExtrFile=0;
ErrCount++;
ExitCode=WARNING;
}
if (IsLabel(NewLhd.FileAttr))
continue;
if (IsDir(NewLhd.FileAttr))
{
if (MainCommand[0]=='P' || MainCommand[0]=='E')
continue;
if (SkipSolid)
{
mprintf(MExtrSkipDir,ArcFileName);
continue;
}
FileCount++;
if (MainCommand[0]=='T')
{
mprintf(MExtrTestDir,ArcFileName);
continue;
}
if ((MDCode=MakeDir(DestFileName,NewLhd.FileAttr))==-1 && errno==ENOENT)
{
CreatePath(DestFileName);
if ((MDCode=MakeDir(DestFileName,NewLhd.FileAttr))==-1 && errno!=EEXIST)
{
mprintf(MExtrErrMkDir,ArcFileName);
ExitCode=WARNING;
}
}
if (MDCode==0)
mprintf(MCreatDir,ArcFileName);
continue;
}
else
{
if (MainCommand[0]=='T' && ExtrFile)
TestMode=1;
if (MainCommand[0]=='P' && ExtrFile)
FilePtr=stdout;
if ((MainCommand[0]=='E' || MainCommand[0]=='X') && ExtrFile)
{
FilePtr=FileCreate(DestFileName,Opt.Overwrite,&UserReject);
if (FilePtr==NULL)
{
if (!UserReject)
{
mprintf(MExtrErrCreat,DestFileName);
ErrCount++;
ExitCode=WARNING;
}
ExtrFile=0;
AllArgsUsed=IsAllArgsUsed();
}
}
}
if (!ExtrFile && SolidType)
{
SkipSolid=1;
TestMode=1;
ExtrFile=1;
}
if (ExtrFile)
{
if (!SkipSolid)
{
if (!TestMode && CheckForDevice(FilePtr))
ErrExit(EWRITE,WRITE_ERROR);
FileCount++;
}
TotalFileCount++;
if (SkipSolid)
mprintf(MExtrSkipFile,ArcFileName);
else
switch(MainCommand[0])
{
case 'T':
mprintf(MExtrTestFile,ArcFileName);
break;
case 'P':
mprintf(MExtrPrinting,ArcFileName);
CheckWriteSize=0;
break;
case 'X':
case 'E':
mprintf(MExtrFile,DestFileName);
break;
}
strcpy(CurExtrFile,SkipSolid ? "":DestFileName);
CurUnpRead=CurUnpWrite=0;
UnpFileCRC=(ArcFormat==OLD) ? 0 : 0xFFFFFFFFL;
if ((*Password!=0) && (NewLhd.Flags & LHD_PASSWORD))
Encryption=NewLhd.UnpVer;
else
Encryption=0;
if (Encryption)
SetCryptKeys(Password);
UnpPackedSize=NewLhd.PackSize;
DestUnpSize=NewLhd.UnpSize;
RdUnpPtr=ArcPtr;
WrUnpPtr=FilePtr;
Suspend=0;
Repack=0;
SkipUnpCRC=SkipSolid;
if (NewLhd.Method==0x30)
UnstoreFile();
else
if (NewLhd.UnpVer<=15)
tunpack(UnpMemory,TotalFileCount>1 && SolidType,OLD_UNPACK);
else
tunpack(UnpMemory,NewLhd.Flags & LHD_SOLID,NEW_UNPACK);
if (!SkipSolid)
AllArgsUsed=IsAllArgsUsed();
if (MainCommand[0]=='P')
CheckWriteSize=1;
if (ArcPtr!=NULL)
tseek(ArcPtr,NextBlockPos,SEEK_SET);
if (!SkipSolid)
if ((ArcFormat==OLD && UnpFileCRC==NewLhd.FileCRC) || (ArcFormat==NEW && UnpFileCRC==~NewLhd.FileCRC))
{
if (MainCommand[0]!='P')
mprintf(MExtrOk);
BrokenFile=0;
}
else
{
if (NewLhd.Flags & LHD_PASSWORD)
mprintf(MEncrBadCRC,ArcFileName);
else
mprintf(MExtrBadCRC,ArcFileName);
ExitCode=CRC_ERROR;
ErrCount++;
BrokenFile=1;
}
if (TestMode==1)
TestMode=0;
else
{
if (MainCommand[0]=='X' || MainCommand[0]=='E')
{
SetOpenFileStat(FilePtr);
tclose(FilePtr);
SetCloseFileStat(DestFileName);
if (BrokenFile && !Opt.KeepBroken)
remove(DestFileName);
}
}
*CurExtrFile=0;
}
}
if (ArcPtr==NULL)
goto GetNextArchive;
if (!ExtrFile)
if (!SolidType)
tseek(ArcPtr,NextBlockPos,SEEK_SET);
else
if (!SkipSolid)
break;
if (AllArgsUsed)
break;
}
free(UnpMemory);
UnpMemory=NULL;
tclose(ArcPtr);
}
if (FileCount==0)
{
mprintf(MExtrNoFiles);
ExitCode=WARNING;
}
else
if (ErrCount==0)
mprintf(MExtrAllOk);
else
mprintf(MExtrTotalErr,ErrCount);
if (TmpPassword!=0)
memset(Password,0,sizeof(Password));
}